package com.imut.lagain.util;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.UUID;

/**
 * 文件上传工具类
 */
@Component
public class FileUtil {
    private static final Logger log = LoggerFactory.getLogger(FileUtil.class);

    
    @Value("${file.upload.path}")
    private String uploadPath;
    
    @Value("${file.access.url}")
    private String accessUrl;
    private static final String[] IMAGE_EXTENSIONS = {".jpg", ".jpeg", ".png", ".gif", ".bmp", ".webp"};
    private static final String[] AUDIO_EXTENSIONS = {".mp3", ".wav", ".m4a", ".aac", ".amr"};
    private static final long MAX_FILE_SIZE = 10 * 1024 * 1024;
    
    /**
     * 上传图片文件
     * @param file 图片文件
     * @return 文件访问URL
     * @throws IOException 上传失败异常
     */
    public String uploadImage(MultipartFile file) throws IOException {
        return uploadFile(file, "images", IMAGE_EXTENSIONS);
    }
    
    /**
     * 上传音频文件
     * @param file 音频文件
     * @return 文件访问URL
     * @throws IOException 上传失败异常
     */
    public String uploadAudio(MultipartFile file) throws IOException {
        return uploadFile(file, "audios", AUDIO_EXTENSIONS);
    }
    
    /**
     * 通用文件上传方法
     * @param file 文件
     * @param subDir 子目录
     * @param allowedExtensions 允许的文件扩展名
     * @return 文件访问URL
     * @throws IOException 上传失败异常
     */
    private String uploadFile(MultipartFile file, String subDir, String[] allowedExtensions) throws IOException {
        validateFile(file, allowedExtensions);
        String originalFilename = file.getOriginalFilename();
        String extension = getFileExtension(originalFilename);
        String newFilename = generateFilename(extension);
        String dateDir = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy/MM/dd"));
        String fullDir = uploadPath + File.separator + subDir + File.separator + dateDir;
        
        Path dirPath = Paths.get(fullDir);
        if (!Files.exists(dirPath)) {
            Files.createDirectories(dirPath);
        }
        String filePath = fullDir + File.separator + newFilename;
        Path targetPath = Paths.get(filePath);
        file.transferTo(targetPath.toFile());
        String relativePath = subDir + "/" + dateDir + "/" + newFilename;
        String fileUrl = accessUrl + "/" + relativePath.replace("\\", "/");
        return fileUrl;
    }
    
    /**
     * 验证文件
     * @param file 文件
     * @param allowedExtensions 允许的扩展名
     * @throws IOException 验证失败异常
     */
    private void validateFile(MultipartFile file, String[] allowedExtensions) throws IOException {
        if (file == null || file.isEmpty()) {
            throw new IOException("文件不能为空");
        }
        
        if (file.getSize() > MAX_FILE_SIZE) {
            throw new IOException("文件大小不能超过10MB");
        }
        
        String originalFilename = file.getOriginalFilename();
        if (originalFilename == null || originalFilename.trim().isEmpty()) {
            throw new IOException("文件名不能为空");
        }
        
        String extension = getFileExtension(originalFilename).toLowerCase();
        boolean isValidExtension = false;
        for (String allowedExt : allowedExtensions) {
            if (allowedExt.equalsIgnoreCase(extension)) {
                isValidExtension = true;
                break;
            }
        }
        
        if (!isValidExtension) {
            throw new IOException("不支持的文件格式: " + extension);
        }
    }
    
    /**
     * 获取文件扩展名
     * @param filename 文件名
     * @return 扩展名（包含点号）
     */
    public String getFileExtension(String filename) {
        if (filename == null || filename.isEmpty()) {
            return "";
        }
        
        int lastDotIndex = filename.lastIndexOf('.');
        if (lastDotIndex == -1 || lastDotIndex == filename.length() - 1) {
            return "";
        }
        
        return filename.substring(lastDotIndex);
    }
    
    /**
     * 生成唯一文件名
     * @param extension 文件扩展名
     * @return 新文件名
     */
    private String generateFilename(String extension) {
        String timestamp = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss"));
        String uuid = UUID.randomUUID().toString().replace("-", "").substring(0, 8);
        return timestamp + "_" + uuid + extension;
    }
    
    /**
     * 删除文件
     * @param fileUrl 文件URL
     * @return 是否删除成功
     */
    public boolean deleteFile(String fileUrl) {
        try {
            if (fileUrl == null || fileUrl.isEmpty()) {
                return false;
            }
            String relativePath = fileUrl.replace(accessUrl + "/", "");
            String filePath = uploadPath + File.separator + relativePath.replace("/", File.separator);
            
            Path path = Paths.get(filePath);
            if (Files.exists(path)) {
                Files.delete(path);
                return true;
            } else {
                log.warn("File not found for deletion: {}", filePath);
                return false;
            }
            
        } catch (Exception e) {
            log.error("Failed to delete file: {}", fileUrl, e);
            return false;
        }
    }
    
    /**
     * 获取文件大小（字节）
     * @param fileUrl 文件URL
     * @return 文件大小，-1表示获取失败
     */
    public long getFileSize(String fileUrl) {
        try {
            if (fileUrl == null || fileUrl.isEmpty()) {
                return -1;
            }
            
            String relativePath = fileUrl.replace(accessUrl + "/", "");
            String filePath = uploadPath + File.separator + relativePath.replace("/", File.separator);
            
            Path path = Paths.get(filePath);
            if (Files.exists(path)) {
                return Files.size(path);
            }
            
        } catch (Exception e) {
            log.error("Failed to get file size: {}", fileUrl, e);
        }
        
        return -1;
    }
    
    /**
     * 检查文件是否存在
     * @param fileUrl 文件URL
     * @return 是否存在
     */
    public boolean fileExists(String fileUrl) {
        try {
            if (fileUrl == null || fileUrl.isEmpty()) {
                return false;
            }
            
            String relativePath = fileUrl.replace(accessUrl + "/", "");
            String filePath = uploadPath + File.separator + relativePath.replace("/", File.separator);
            
            return Files.exists(Paths.get(filePath));
            
        } catch (Exception e) {
            log.error("Failed to check file existence: {}", fileUrl, e);
            return false;
        }
    }
    
    /**
     * 验证文件类型是否有效
     * @param fileName 文件名
     * @return 是否为有效文件类型
     */
    public boolean isValidFileType(String fileName) {
        if (fileName == null || fileName.isEmpty()) {
            return false;
        }
        
        String extension = getFileExtension(fileName).toLowerCase();
        for (String imageExt : IMAGE_EXTENSIONS) {
            if (imageExt.equalsIgnoreCase(extension)) {
                return true;
            }
        }
        for (String audioExt : AUDIO_EXTENSIONS) {
            if (audioExt.equalsIgnoreCase(extension)) {
                return true;
            }
        }
        
        return false;
    }
    
    /**
     * 生成文件名（公共方法）
     * @param originalFileName 原始文件名
     * @return 新文件名
     */
    public String generateFileName(String originalFileName) {
        String extension = getFileExtension(originalFileName);
        return generateFilename(extension);
    }
    

}

